package multithread.framework.threadmethod;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorService;

import multithread.framework.annotation.ThreadGroupFor;
import multithread.framework.exception.ConfigurationException;
/**
 * A group of {@link ThreadMethod}
 * @author dailey_dai
 */
public class ThreadMethodGroup implements IThreadMethod {
	private List<ThreadMethod> threadmethodList = null;

	private ThreadGroupFor threadGroupFor;

	public ThreadMethodGroup() {
		threadmethodList = new ArrayList<ThreadMethod>();
	}

	public ThreadMethodGroup(ThreadGroupFor threadGroupFor) {
		this();
		this.threadGroupFor = threadGroupFor;
	}

	public void setThreadGroupFor(ThreadGroupFor threadGroupFor) {
		this.threadGroupFor = threadGroupFor;
	}

	public ThreadGroupFor getThreadGroupFor() {
		return threadGroupFor;
	}

	public boolean addThreadMethod(ThreadMethod method) {
		if (threadmethodList.contains(method)) {
			throw new ConfigurationException("");
		}
		return threadmethodList.add(method);
	}

	public int size() {
		return threadmethodList.size();
	}

	public boolean isEmpty() {
		return threadmethodList.isEmpty();
	}

	public Iterator<ThreadMethod> iterator() {
		return threadmethodList.iterator();
	}

	/**
	 * 
	 * @return FutureQueue<ThreadResult>
	 */
	@Override
	public FutureQueue<ThreadResult> invoke(ExecutorService service,
			Object instance, Class<? extends Annotation>... annotationClzs) {
		FutureQueue<ThreadResult> futureQueue = new FutureQueue<ThreadResult>();
		for (ThreadMethod method : threadmethodList) {
			futureQueue.addQueue(method.invoke(service, instance,
					annotationClzs));
		}
		return futureQueue;
	}

	@Override
	public FutureQueue<ThreadResult> invoke(
			CompletionService<ThreadResult> service, Object instance,
			Class<? extends Annotation>... annotationClzs) {
		FutureQueue<ThreadResult> futureQueue = new FutureQueue<ThreadResult>();
		for (ThreadMethod method : threadmethodList) {
			futureQueue.addQueue(method.invoke(service, instance,
					annotationClzs));
		}
		return futureQueue;
	}

	@Override
	public int getThreadCount() {
		int totalThreadCount = 0;
		for (ThreadMethod method : threadmethodList) {
			totalThreadCount += method.getThreadCount();
		}
		return totalThreadCount;
	}

	@Override
	public String toString() {
		return "ThreadMethodGroup [threadGroupFor=" + threadGroupFor + "]";
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ThreadMethodGroup other = (ThreadMethodGroup) obj;
		if (threadGroupFor == null) {
			if (other.threadGroupFor != null)
				return false;
		} else if (!threadGroupFor.equals(other.threadGroupFor))
			return false;
		return true;
	}

	public List<ThreadMethod> getThreadmethodList() {
		return threadmethodList;
	}

}
